package com.wxmp.dubbo.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Service;
import com.wxmp.config.WxCpConfiguration;
import com.wxmp.dubbo.dto.Message;
import com.wxmp.dubbo.service.WechatDubboService;
import com.wxmp.userwechat.domain.SysUserCpWechatEntity;
import com.wxmp.userwechat.domain.SysUserNotifyEntity;
import com.wxmp.userwechat.domain.SysUserWechatEntity;
import com.wxmp.userwechat.service.SysUserCpWechatService;
import com.wxmp.userwechat.service.SysUserNotifyService;
import com.wxmp.userwechat.service.SysUserWechatService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpMessage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;

@Api(value = "微信相关dubbo接口")
@Component
@Service
/**
 * 微信dubbo接口
 * @author song.wang
 * @date 2019年4月16日
 */

public class WechatDubboServiceImpl implements WechatDubboService {
	private static final Logger logger = LoggerFactory.getLogger(WechatDubboServiceImpl.class);
	@Autowired
	private WxMpService wxMpService;
	@Autowired
	private SysUserNotifyService sysUserNotifyService;
	@Autowired
	private SysUserWechatService sysUserWechatService;
	@Autowired
	private SysUserCpWechatService sysUserCpWechatService;

	@Value("${wechat.mp.appid}")
	public String wxAppId;
	
	@Override
	@ApiOperation(value = "生成二维码", notes = "生成带参数的公众号二维码，用于绑定消息")
	public String createQrcodeByAppId(@ApiParam(value = "调用公众号appid") String appid,@ApiParam(value = "二维码携带参数") String sceneStr) throws Exception {
		logger.info("生成微信公众号二维码");
		WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.switchoverTo(appid).getQrcodeService().qrCodeCreateLastTicket(sceneStr);
		String qrcodeUrl = wxMpQrCodeTicket.getUrl();
		logger.info("picUrl===" + wxMpService.switchoverTo(appid).getQrcodeService().qrCodePictureUrl(wxMpQrCodeTicket.getTicket(), true));
		// String qrcodeUrl =
		// wxMpService.getQrcodeService().qrCodePictureUrl(wxMpQrCodeTicket.getTicket(),true);
		logger.info("公众号二维码地址为：{}", qrcodeUrl);
		return qrcodeUrl;
	}

	@Override
	@ApiOperation(value = "生成二维码", notes = "生成带参数的公众号二维码，用于绑定消息")
	public String createQrcode(@ApiParam(value = "二维码携带参数") String sceneStr) throws Exception {
		return this.createQrcodeByAppId(wxAppId, sceneStr);
	}
	
	@Override
	@ApiOperation(value = "发送模板消息", notes = "发送模板消息，可传入多个openid")
	public void sendTemplateMsgByAppId(@ApiParam(value = "调用公众号appid") String appid,
			@ApiParam(value = "openid数组") String[] openids,
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) {
		logger.info("进入发送模板消息接口");
		try {
			WxMpTemplateMessage sendTemplateMessage = new WxMpTemplateMessage();
			sendTemplateMessage.setTemplateId(templateMessage.getTemplateId());
			sendTemplateMessage.setToUser(templateMessage.getToUser());
			sendTemplateMessage.setUrl(templateMessage.getUrl());
			List<WxMpTemplateData> dataList = new ArrayList<WxMpTemplateData>();
			dataList.addAll(templateMessage.getData());
			sendTemplateMessage.setData(dataList);
			for (String openid : openids) {
				if (openid != null) {
					int i = 1;
					sendTemplateMessage.setToUser(openid);
					String result = wxMpService.switchoverTo(appid).getTemplateMsgService().sendTemplateMsg(sendTemplateMessage);
					i++;
					logger.info("共发送【{}】条，发送模板消息结果：【{}】", i + "/" + openids.length, result);
				}
			}
		} catch (WxErrorException e) {
			e.printStackTrace();
			logger.error("发送微信模板消息异常", e);
		}
	}
	@Override
	@ApiOperation(value = "发送模板消息", notes = "发送模板消息，可传入多个openid")
	public void sendTemplateMsg(@ApiParam(value = "openid数组") String[] openids,
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) {
		this.sendTemplateMsgByAppId(wxAppId, openids, templateMessage);
	}

	@Override
	@ApiOperation(value = "发送模板消息多URL", notes = "发送模板消息多URL，可传入多个openid，每个模板对应一个URL")
	public void sendTemplateMsgByAppId(@ApiParam(value = "调用公众号appid") String appid,
			@ApiParam(value = "openid数组") String[] openids,
			@ApiParam(value = "消息url数组") String[] sendUrls,
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) {
		logger.info("进入发送模板消息接口多URL");
		if (openids.length != sendUrls.length) {
			logger.info("接口参数错误，openid和sendUrl数量不一致");
			return;
		}
		try {
			WxMpTemplateMessage sendTemplateMessage = new WxMpTemplateMessage();
			sendTemplateMessage.setTemplateId(templateMessage.getTemplateId());
			sendTemplateMessage.setToUser(templateMessage.getToUser());
			sendTemplateMessage.setUrl(templateMessage.getUrl());
			List<WxMpTemplateData> dataList = new ArrayList<WxMpTemplateData>();
			dataList.addAll(templateMessage.getData());
			sendTemplateMessage.setData(dataList);
			for (int i = 0; i < openids.length; i++) {
				String openid = openids[i];
				if (openid != null) {
					String sendUrl = sendUrls[i];
					sendTemplateMessage.setToUser(openid);
					sendTemplateMessage.setUrl(sendUrl);
					String result = wxMpService.switchoverTo(appid).getTemplateMsgService().sendTemplateMsg(sendTemplateMessage);
					logger.info("共发送【{}】条，发送模板消息多URL结果：【{}】", (i + 1) + "/" + openids.length, result);
				}
			}
		} catch (WxErrorException e) {
			e.printStackTrace();
			logger.error("发送微信模板消息多URL异常", e);
		}
	}
	
	@Override
	@ApiOperation(value = "发送模板消息多URL", notes = "发送模板消息多URL，可传入多个openid，每个模板对应一个URL")
	public void sendTemplateMsg(@ApiParam(value = "openid数组") String[] openids,
			@ApiParam(value = "消息url数组") String[] sendUrls,
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) {
		this.sendTemplateMsgByAppId(wxAppId, openids, sendUrls, templateMessage);
	}

	@Override
	@ApiOperation(value = "获取微信信息", notes = "根据用户id获取微信信息", httpMethod = "GET")
	public Message getUserWechatInfo(@ApiParam(value = "用户id") String userId) {
		Message message = new Message();
		try {
			SysUserWechatEntity sysUserWechatEntity = sysUserWechatService.getSysUserWechatByUserId(userId);
			boolean hasUser = false;
			if (sysUserWechatEntity != null) {
				hasUser = true;
				message.addData("nickName", sysUserWechatEntity.getNickname());
				message.addData("imageUrl", sysUserWechatEntity.getHeadimgurl());
			} else {
				message.addData("nickName", "");
				message.addData("imageUrl", "");
			}
			message.addData("status", hasUser);
			logger.info("用户id【{}】请求获取微信用户接口成功！", userId);
			return message.ok(1000, "获取成功!");
		} catch (Exception e) {
			logger.error("获取微信用户信息错误", e);
			return message.error(9000, "获取微信用户信息错误");
		}
	}

	@Override
	@ApiOperation(value = "用户绑定微信", notes = "根据用户id、微信openid绑定微信")
	public Message bindWechatByAppId(@ApiParam(value = "微信公众号appid") String appid, 
			@ApiParam(value = "用户id") Long userId, 
			@ApiParam(value = "微信openid") String openid) {
		Message message = new Message();
		try {
			SysUserWechatEntity wechat = sysUserWechatService.getSysUserWechatByUserId(userId.toString());
			if (wechat == null) {
				// 没绑定过
				SysUserWechatEntity sysUserWechat = new SysUserWechatEntity();
				WxMpUser wxMpUser = wxMpService.switchoverTo(appid).getUserService().userInfo(openid);
				sysUserWechat.setCity(wxMpUser.getCity());
				sysUserWechat.setCountry(wxMpUser.getCountry());
				sysUserWechat.setHeadimgurl(wxMpUser.getHeadImgUrl());
				sysUserWechat.setNickname(wxMpUser.getNickname());
				sysUserWechat.setProvince(wxMpUser.getProvince());
				sysUserWechat.setSex(wxMpUser.getSex());
				sysUserWechat.setUnionid(wxMpUser.getUnionId());
				sysUserWechat.setUserId(userId);
				sysUserWechat.setCreateTime(new Date());
				sysUserWechat.setOpenid(openid);
				sysUserWechat.setUserType((short) 1);
				sysUserWechatService.saveSysUserWechat(sysUserWechat);
				logger.info("用户id【{}】请求绑定微信调用接口成功！", userId);
				return message.ok(1000, "绑定成功！");
			} else {
				logger.info("用户id【{}】请求绑定微信调用接口成功！", userId);
				return message.error(9000, "该账号已经绑定过微信，请先解除绑定！");
			}
		} catch (Exception e) {
			logger.error("用户id【{}】请求绑定微信出错", e);
			return message.error(9000, "微信绑定出错，请联系管理员！");
		}
	}
	@Override
	@ApiOperation(value = "用户绑定微信", notes = "根据用户id、微信openid绑定微信")
	public Message bindWechat(@ApiParam(value = "用户id") Long userId, 
			@ApiParam(value = "微信openid") String openid) {
		return this.bindWechatByAppId(wxAppId, userId, openid);
	}

	@Override
	@ApiOperation(value = "微信解除绑定", notes = "根据用户id解绑微信")
	public void unbindWechat(@ApiParam(value = "用户id") String userId) {
		logger.info("微信解除绑定，userId【{}】", userId);
		sysUserWechatService.removeByUserId(userId);
	}

	@Override
	@ApiOperation(value = "更新绑定状态", notes = "根据用户id和绑定状态，更新用户的绑定状态")
	public Message updateUserNotify(@ApiParam(value = "用户id") String userId,
			@ApiParam(value = "邮件绑定状态") Boolean useEmail, @ApiParam(value = "微信绑定状态") Boolean useWechat,
			@ApiParam(value = "系统消息绑定状态") Boolean useSystem) {
		Message message = new Message();
		SysUserNotifyEntity sysUserNotifyEntity = sysUserNotifyService.getUserNotify(Long.valueOf(userId));
		sysUserNotifyEntity.setEmailNotify(useEmail ? (short) 1 : (short) 0);
		sysUserNotifyEntity.setWechatNotify(useWechat ? (short) 1 : (short) 0);
		sysUserNotifyEntity.setSystemNotify(useSystem ? (short) 1 : (short) 0);
		sysUserNotifyService.updateUserNotify(sysUserNotifyEntity);
		return message.ok(1000, "用户通知设置成功!");
	}

	@Override
	@ApiOperation(value = "获取用户通知状态", notes = "根据用户id获取用户通知状态", httpMethod = "GET")
	public Message getUserNotify(@ApiParam(value = "用户id") String userId) {
		Message message = new Message();
		SysUserNotifyEntity sysUserNotifyEntity = sysUserNotifyService.getUserNotify(Long.valueOf(userId));
		message.addData("useEmail", sysUserNotifyEntity.getEmailNotify() == 1);
		message.addData("useWechat", sysUserNotifyEntity.getWechatNotify() == 1);
		message.addData("useSystem", sysUserNotifyEntity.getSystemNotify() == 1);
		return message.ok(1000, "获取用户通知设置成功!");
	}

	@Override
	@ApiOperation(value = "发送企业微信卡片消息", notes = "卡片消息发送", httpMethod = "POST")
	public Message sendWxCpCardMsg(@ApiParam(value = "发送的用户id，多个以逗号分隔") String userIds,
			@ApiParam(value = "消息标题") String title, @ApiParam(value = "消息文本内容") String content,
			@ApiParam(value = "消息跳转地址") String url) {
		Message result = new Message();
		String[] users = userIds.split(",");
		Long[] userids = (Long[]) ConvertUtils.convert(users, Long.class);
		StringBuffer sendUser = new StringBuffer();
		List<SysUserCpWechatEntity> listU = sysUserCpWechatService.listSysUserCpWechatByUserIds(userids);
		for (SysUserCpWechatEntity user : listU) {
			// 此处设置的消息接受者id是企业微信用户id
			sendUser.append(user.getWxUserId());
			sendUser.append("|");
		}
		try {
			if (StringUtils.isNotEmpty(sendUser.toString())) {
				WxCpMessage message = WxCpMessage.TEXTCARD().build();
				message.setTitle(title);
				message.setDescription(content);
				message.setUrl(url);
				message.setBtnTxt("查看详情");
				message.setToUser(sendUser.toString());
				WxCpConfiguration.getCpService(1000003).messageSend(message);
			}
		} catch (WxErrorException e) {
			e.printStackTrace();
			return result.error(9000, "发送卡片消息失败!");
		}
		return result.ok(1000, "发送卡片消息成功!");
	}

	@Override
	@ApiOperation(value = "获取未激活的企业用户", notes = "根据用户id获取未激活的企业用户", httpMethod = "GET")
	public Message listUserNotInCpWechat(@ApiParam(value = "用户id，多个以逗号分隔") String userIds) {
		logger.info("根据用户查询返回未激活的企业用户接口");
		Message result = new Message();
		try {
			String[] users = userIds.split(",");
			List<String> listUser = sysUserCpWechatService.listUserNotInCpWechat(users);
			result.addData("listUser", listUser);
		} catch (Exception e) {
			return result.error(9000, "根据用户查询返回未激活的企业用户失败!");
		}
		return result.ok(1000, "根据用户查询返回未激活的企业用户成功！");
	}

	@Override
	public void sendTemplateMsgByAppId(@ApiParam(value = "微信公众号appid") String appid,
			@ApiParam(value = "用户id（使用“,”分隔）") String userIds, 
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) throws Exception {
		logger.info("进入根据用户id发送模板消息接口");
		try {
			WxMpTemplateMessage sendTemplateMessage = new WxMpTemplateMessage();
			sendTemplateMessage.setTemplateId(templateMessage.getTemplateId());
			sendTemplateMessage.setUrl(templateMessage.getUrl());
			List<WxMpTemplateData> dataList = new ArrayList<WxMpTemplateData>();
			dataList.addAll(templateMessage.getData());
			sendTemplateMessage.setData(dataList);
			String[] users = userIds.split(",");
			for (int i = 0; i < users.length; i++) {
				String userId = users[i];
				if (userId != null) {
					SysUserWechatEntity sysUserWechatEntity = sysUserWechatService.getSysUserWechatByUserId(userId);
					if (sysUserWechatEntity != null) {
						sendTemplateMessage.setToUser(sysUserWechatEntity.getOpenid());
						String result = wxMpService.switchoverTo(appid).getTemplateMsgService().sendTemplateMsg(sendTemplateMessage);
						logger.info("共发送【{}】条，根据用户id发送模板消息结果：【{}】", (i + 1) + "/" + users.length, result);
					}
				}
			}
		} catch (WxErrorException e) {
			e.printStackTrace();
			logger.error("根据用户id发送微信模板消息异常", e);
			throw e;
		}
	}
	@Override
	public void sendTemplateMsg(@ApiParam(value = "用户id（使用“,”分隔）") String userIds, 
			@ApiParam(value = "模板消息类，参见com.github.binarywang") WxMpTemplateMessage templateMessage) throws Exception {
		this.sendTemplateMsgByAppId(wxAppId, userIds, templateMessage);
	}

}
